﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using HtmlAgilityPack;
using Core.Utils;

namespace Core.Extentions
{
    public static class StringExtentions
    {
        public static string ResizeText(this string str, int amountChars, string readMoreLink)
        {
            if (str.ClearHTMLTags().Count() > amountChars)
            {
                bool inTag = false;
                int cntr = 0;
                int cntrContent = 0;
                foreach (Char c in str)
                {
                    if (cntrContent == amountChars) break;

                    cntr++;
                    if (c == '<')
                    {
                        inTag = true;
                        continue;
                    }
                    else if (c == '>')
                    {
                        inTag = false;
                        continue;
                    }

                    if (!inTag) cntrContent++;
                }

                string substr = string.Empty;
                int indexOfSpace = str.IndexOf(' ', cntr);
                if (indexOfSpace > 0)
                {
                    substr = str.Substring(0, indexOfSpace);
                }
                else
                {
                    substr = str.Substring(0, cntr);
                }

                //search for nonclosed tags
                MatchCollection openedTags = new Regex("<[^/](.|\n)*?>").Matches(substr);
                MatchCollection closedTags = new Regex("<[/](.|\n)*?>").Matches(substr);

                for (int i = openedTags.Count - closedTags.Count; i >= 1; i--)
                {
                    if (!openedTags[closedTags.Count + i - 1].Value.Contains("br"))
                    {
                        string closingTag = "</" + openedTags[closedTags.Count + i - 1].Value.Substring(1);
                        substr += closingTag;
                    }
                }

                return substr + readMoreLink;
            }

            return str;
            
        }

        public static bool UrlConntainsGuid(this string str)
        {
            Regex format = new Regex(
                "^[A-Fa-f0-9]{32}$|" +
                "^({|\\()?[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}(}|\\))?$|" +
                "^({)?[0xA-Fa-f0-9]{3,10}(, {0,1}[0xA-Fa-f0-9]{3,6}){2}, {0,1}({)([0xA-Fa-f0-9]{3,4}, {0,1}){7}[0xA-Fa-f0-9]{3,4}(}})$");

            string[] saUrl = str.Split('/');
            foreach (string parts in saUrl)
            {
                string[] items = parts.Split('.');
                foreach (var item in items)
                {
                    Match match = format.Match(item);
                    if (match.Success)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static string UppercaseFirst(this string str)
        {
            // Check for empty string.
            if (string.IsNullOrEmpty(str))
            {
                return string.Empty;
            }
            // Return char and concat substring.
            return char.ToUpper(str[0]) + str.Substring(1).ToLower();
        }

        public static string ParseUrl(this string str)
        {
            string strTemp = str.Trim();
            // Regex creation
            Regex regA = new Regex("[ã|à|â|ä|á|å]");
            Regex regAA = new Regex("[Ã|À|Â|Ä|Á|Å]");
            Regex regE = new Regex("[é|è|ê|ë]");
            Regex regEE = new Regex("[É|È|Ê|Ë]");
            Regex regI = new Regex("[í|ì|î|ï]");
            Regex regII = new Regex("[Í|Ì|Î|Ï]");
            Regex regO = new Regex("[õ|ò|ó|ô|ö]");
            Regex regOO = new Regex("[Õ|Ó|Ò|Ô|Ö]");
            Regex regU = new Regex("[ù|ú|û|ü|µ]");
            Regex regUU = new Regex("[Ü|Ú|Ù|Û]");
            Regex regY = new Regex("[ý|ÿ]");
            Regex regYY = new Regex("[Ý]");
            Regex regAE = new Regex("[æ]");
            Regex regAEAE = new Regex("[Æ]");
            Regex regOE = new Regex("[œ]");
            Regex regOEOE = new Regex("[Œ]");
            Regex regC = new Regex("[ç]");
            Regex regCC = new Regex("[Ç]");
            Regex regDD = new Regex("[Ð]");
            Regex regN = new Regex("[ñ]");
            Regex regNN = new Regex("[Ñ]");
            Regex regS = new Regex("[š]");
            Regex regSS = new Regex("[Š]");
            strTemp = regA.Replace(strTemp, "a");
            strTemp = regAA.Replace(strTemp, "A");
            strTemp = regE.Replace(strTemp, "e");
            strTemp = regEE.Replace(strTemp, "E");
            strTemp = regI.Replace(strTemp, "i");
            strTemp = regII.Replace(strTemp, "I");
            strTemp = regO.Replace(strTemp, "o");
            strTemp = regOO.Replace(strTemp, "O");
            strTemp = regU.Replace(strTemp, "u");
            strTemp = regUU.Replace(strTemp, "U");
            strTemp = regY.Replace(strTemp, "y");
            strTemp = regYY.Replace(strTemp, "Y");
            strTemp = regAE.Replace(strTemp, "ae");
            strTemp = regAEAE.Replace(strTemp, "AE");
            strTemp = regOE.Replace(strTemp, "oe");
            strTemp = regOEOE.Replace(strTemp, "OE");
            strTemp = regC.Replace(strTemp, "c");
            strTemp = regCC.Replace(strTemp, "C");
            strTemp = regDD.Replace(strTemp, "D");
            strTemp = regN.Replace(strTemp, "n");
            strTemp = regNN.Replace(strTemp, "N");
            strTemp = regS.Replace(strTemp, "s");
            strTemp = regSS.Replace(strTemp, "S");

            strTemp = strTemp.ToLower().Replace('\'','-').Replace('/','-');
            // remove entities
            strTemp = Regex.Replace(strTemp, @"&\w+;", "");
            // remove anything that is not letters, numbers, dash, or space
            strTemp = Regex.Replace(strTemp, @"[^a-z0-9\-\s]", "");
            // replace spaces
            strTemp = strTemp.Replace(' ', '-');
            // collapse dashes
            strTemp = Regex.Replace(strTemp, @"-{2,}", "-");
            // trim excessive dashes at the beginning
            strTemp = strTemp.Trim(new[] { '-' });

            return strTemp;

        }

        public static string ClearHTMLTags(this string str)
        {
            Regex rsClearHTML = new Regex("<(.|\n)+?>");
            string clearHTML = rsClearHTML.Replace(str, String.Empty).Replace("\n", string.Empty);
            return HttpContext.Current.Server.HtmlEncode(clearHTML);
        }

        public static string CleanWordTags(this string html)
        {
            // removing all HTML comment
            html = Regex.Replace(html, @"<!--(\w|\W)+?-->", string.Empty, RegexOptions.IgnoreCase);

            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(html);
            // start by completely removing all unwanted tags 
            var elements = doc.DocumentNode.SelectNodes("//font|//span|//xml|//del|//ins|//meta|//link|//style");

            if (elements != null)
            {
                foreach (var element in elements)
                {
                    element.ParentNode.RemoveChild(element, true);
                }
            }

            // then by completely removing all unwanted attribute 
            elements = doc.DocumentNode.SelectNodes("//*[@class or @style]");

            if (elements != null)
            {
                foreach (var element in elements)
                {
                    if(element.Attributes["style"] != null)
                    {
                        element.Attributes["style"].Remove();
                    }

                    if (element.Attributes["class"] != null)
                    {
                        element.Attributes["class"].Remove();
                    }
                }
            }

            // Clear empty tags
            elements = doc.DocumentNode.SelectNodes("//p|//b|//u|//i");
            if (elements != null)
            {
                foreach (var element in elements)
                {
                    if (element.InnerText.Trim() == string.Empty)
                    {
                        element.ParentNode.RemoveChild(element, true);
                    }
                }
            }

            // Change urderline to bold
            elements = doc.DocumentNode.SelectNodes("//u");
            if (elements != null)
            {
                foreach (var element in elements)
                {
                    var newNodeStr = "<b>" + element.InnerHtml + "</b>";
                    var newNode = HtmlNode.CreateNode(newNodeStr);

                    element.ParentNode.ReplaceChild(newNode, element);
                }
            }

            html = doc.DocumentNode.OuterHtml;

            // Remove spacing
            html = Regex.Replace(html, @"\s+", " ", RegexOptions.Singleline);

            return html;
        }

        public static string AddUrlInHref(this string html, Uri u)
        {
            return AddUrlIn(html, u, false);
        }

        public static string AddUrlInSrc(this string html, Uri u)
        {
            return AddUrlIn(html, u, true);
        }

        public static string ClearBreak(this string html)
        {
            return Regex.Replace(html, @"(<br\s*/?>\s*)+", "<br />", RegexOptions.IgnoreCase | RegexOptions.Multiline);
        }

        private static string AddUrlIn(string html, Uri u, bool isImageUrl)
        {
            string url = u.AbsoluteUri;
            if (u.AbsolutePath != string.Empty)
            {
                url = url.Replace("http://", string.Empty);                
                url = url.Replace(u.AbsolutePath, string.Empty);
                url = "http://" + url;
            }
            if (u.Query != string.Empty)
            {
                url = url.Replace(u.Query, string.Empty);
            }

            if (isImageUrl)
            {

                return Regex.Replace(html, "(<img .*?src=\")((?!http://).+?)\"", "$1" + url + "$2" + u.Query + "\"", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            }
            else
            {
                return Regex.Replace(html, @"(<a .*?href="")((?!http://).+?)""", "$1" + url + "$2" + u.Query + "\"", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            }
        }
    }
}
